package edu.mbb.mybatis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import edu.mbb.core.Configuration;

public class MyMapperProxy implements InvocationHandler {
	private MySqlSession sqlSession;

	public MyMapperProxy() {
	}

	public MyMapperProxy(MySqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("--------");
		// 类名字
		String mapperClass = method.getDeclaringClass().getName();
		// 方法的名字
		String name = method.getName();
		Class<?> returnType = method.getReturnType();
		Map<String, Object> xmlByInfaceName = (Map<String, Object>) Configuration.getXmlByInfaceName(mapperClass);
		// 得到这个方法的sql
		String sql = xmlByInfaceName.get(name).toString();
		// 判断sql中的 变量值

		/*
		 * SELECT ar.id, ar.aut_id, ar.title, ar.type, ar.content,
		 * ar.create_time, au.name, au.age, au.sex, au.email FROM article ar,
		 * author au WHERE ar.aut_id = au.id AND ar.id =
		 */
		// #{id}
		// Parameter[] parameters = method.getParameters();
		sql = replaceSql(sql, args, mapperClass + name);
		Object selectOne = sqlSession.selectOne(sql, returnType, mapperClass + name);
		System.out.println(sql);
		return selectOne;
	}

	public String replaceSql(String sql, Object[] args, String mapperClass) {
		// String temp = "SELECT ar.id, ar.aut_id, ar.title, ar.type,
		// ar.content,ar.create_time, au.name, au.age, au.sex, au.email
		// FROMarticle ar, author auWHERe ar.aut_id = au.id AND ar.id = #{id}
		// and id=15";
		// 带？的sql
		String parse = parse(sql, "#{", "}", Configuration.getXmlArgs(mapperClass), Configuration.getArgsValues(),
				args);
		return parse;
	}

	public static String parse(String text, String openToken, String closeToken, List<String> args,
			Map<String, Object> argsValue, Object[] temp) {
		if (text == null || text.isEmpty()) {
			return "";
		}
		char[] src = text.toCharArray();
		int offset = 0;
		// search open token
		int start = text.indexOf(openToken, offset);
		if (start == -1) {
			return text;
		}
		final StringBuilder builder = new StringBuilder();
		StringBuilder expression = null;
		int i = 0;
		while (start > -1) {
			if (start > 0 && src[start - 1] == '\\') {
				// this open token is escaped. remove the backslash and
				// continue.
				builder.append(src, offset, start - offset - 1).append(openToken);
				offset = start + openToken.length();
			} else {
				// found open token. let's search close token.
				if (expression == null) {
					expression = new StringBuilder();
				} else {
					expression.setLength(0);
				}
				builder.append(src, offset, start - offset);
				builder.append("?");

				System.out.println(builder.toString());
				offset = start + openToken.length();
				System.out.println(offset);
				int end = text.indexOf(closeToken, offset);
				System.out.println(end);
				while (end > -1) {
					if (end > offset && src[end - 1] == '\\') {
						// this close token is escaped. remove the backslash and
						// continue.
						expression.append(src, offset, end - offset - 1).append(closeToken);

						offset = end + closeToken.length();
						System.out.println(offset);
						end = text.indexOf(closeToken, offset);
					} else {
						expression.append(src, offset, end - offset);
						args.add(expression.toString());
						System.out.println(expression.toString());

						argsValue.put(expression.toString(), temp[i]);
						i++;
						System.out.println(expression.toString());
						offset = end + closeToken.length();
						System.out.println(offset);
						break;
					}
				}
				if (end == -1) {
					// close token was not found.
					builder.append(src, start, src.length - start);
					offset = src.length;
				} else {
					// builder.append(handler.handleToken(expression.toString()));
					offset = end + closeToken.length();
				}
			}
			start = text.indexOf(openToken, offset);
		}
		if (offset < src.length) {
			builder.append(src, offset, src.length - offset);
		}
		System.out.println(argsValue);
		System.err.println(args);
		return builder.toString();
	}

	public static void main(String[] args) {
		String temp = "SELECT ar.id, ar.aut_id, ar.title, ar.type, ar.content,ar.create_time, au.name, au.age, au.sex, au.email FROMarticle ar, author auWHERe ar.aut_id = #{test} AND ar.id = #{id} and id=18";
		String parse = parse(temp, "#{", "}", Lists.newArrayList(), Maps.newHashMap(), new Object[] { "100", "200" });
		System.out.println(parse);
	}
}
